﻿//using System;
//using System.Collections.Concurrent;
//using System.Threading;
//using PoolKit.Strategies.Repairing;
//using PoolKit.Strategies.ReusePreparation;
//
//namespace PoolKit
//{ TODO: delete or create an equivalent (target of opportunity for next releases)
//    /// <summary>
//    ///
//    /// </summary>
//    /// <typeparam name="TResource"></typeparam>
//    internal class AcceptorArmedWithDedicatedThreads<TResource> : IAcceptor<TResource>
//        where TResource : class
//    {
//        private const int MaxWorkingThreadCount = 10;
//        private readonly IResourceCollection<TResource> _resourceCollection;
//        private readonly ReusePreparationStrategy<TResource> _reusePreparationStrategy;
//        private readonly Thread[] _workingThreads;
//        private readonly BlockingCollection<Command> _commands = new BlockingCollection<Command>();
//        private readonly object _disposalInProgressCriticalSection = new object();
//        private readonly RepairStrategy<TResource> _repairStrategy;
//        private bool _disposed;
//        private int _activeWorkingThreads;
//        private readonly ManualResetEvent _allThreadsQuit = new ManualResetEvent(false);
//        private volatile bool _isDisposing = false;
//
//        /// <summary>
//        /// 
//        /// </summary>
//        /// <param name="numberOfWorkerThreads"></param>
//        /// <param name="resourceCollection"></param>
//        /// <param name="reusePreparationStrategy"></param>
//        /// <param name="repairStrategy"></param>
//        /// <exception cref="ArgumentNullException"></exception>
//        /// <exception cref="ArgumentOutOfRangeException"></exception>
//        public AcceptorArmedWithDedicatedThreads(int numberOfWorkerThreads, IResourceCollection<TResource> resourceCollection, ReusePreparationStrategy<TResource> reusePreparationStrategy, RepairStrategy<TResource> repairStrategy)
//        {
//            if (resourceCollection == null) throw new ArgumentNullException("resourceCollection");
//            if (reusePreparationStrategy == null) throw new ArgumentNullException("reusePreparationStrategy");
//            if (repairStrategy == null) throw new ArgumentNullException("repairStrategy");
//
//            if ((numberOfWorkerThreads <= 0) || (numberOfWorkerThreads > MaxWorkingThreadCount))
//            {
//                throw new ArgumentOutOfRangeException("numberOfWorkerThreads", Resources.ExpectingPositiveNumberLessThan.FormatWith(MaxWorkingThreadCount));
//            }
//
//            _resourceCollection = resourceCollection;
//
//            _repairStrategy = ((numberOfWorkerThreads > 1) ? repairStrategy.ToThreadSafe() : repairStrategy);
//
//            _reusePreparationStrategy = ((numberOfWorkerThreads > 1) ? reusePreparationStrategy.ToThreadSafe() : reusePreparationStrategy);
//
//            _workingThreads = new Thread[numberOfWorkerThreads];
//
            // Note: too much work in constructor, left for later refactoring (non-critical).
//            InitializeAndStartWorkingThreads(numberOfWorkerThreads);
//        }
//
//        private void InitializeAndStartWorkingThreads(int numberOfWorkerThreads)
//        {
//            try
//            {
//                for (int i = 0; i < numberOfWorkerThreads; i++)
//                {
//                    _workingThreads[i] = new Thread(ProcessResourceTasks) { IsBackground = true };
//                    _workingThreads[i].Start();
//
//                    Interlocked.Increment(ref _activeWorkingThreads);
//                }
//            }
//            catch (Exception)
//            {
//                Dispose();
//
//                throw;
//            }
//        }
//
//        /// <summary>
//        /// 
//        /// </summary>
//        /// <param name="resourceToBeReused"></param>
//        /// <exception cref="ArgumentNullException"></exception>
//        /// <exception cref="ObjectDisposedException"></exception>
//        public void Accept(TResource resourceToBeReused)
//        {
//            lock (_disposalInProgressCriticalSection)
//            {
//                ThrowIfDisposed();
//
//                if (resourceToBeReused == null) throw new ArgumentNullException("resourceToBeReused");
//
//                _commands.Add(
//                    new PrepareForReuseCommand<TResource>(
//                        _reusePreparationStrategy,
//                        _resourceCollection,
//                        resourceToBeReused));
//            }
//        }
//
//        private void ThrowIfDisposed()
//        {
//            if (_disposed)
//            {
//                throw new ObjectDisposedException(this.GetType().FullName);
//            }
//        }
//
//        /// <summary>
//        /// 
//        /// </summary>
//        /// <param name="resource"></param>
//        /// <exception cref="ArgumentNullException"></exception>
//        /// <exception cref="ObjectDisposedException"></exception>
//        public void AcceptBroken(TResource resource)
//        {
//            lock (_disposalInProgressCriticalSection)
//            {
//                ThrowIfDisposed();
//
//                if (resource == null) throw new ArgumentNullException("resource");
//
//                _commands.Add(new RepairAndPrepareForReuseCommand<TResource>(_reusePreparationStrategy, _resourceCollection, resource, _repairStrategy));
//            }
//        }
//
//        private void ProcessResourceTasks()
//        {
//            try
//            {
//                while (!_isDisposing)
//                {
//                    DequeueAndRunTask();
//                }
//
//                DrainCommandQueue();
//            }
//            finally
//            {
//                if (Interlocked.Decrement(ref _activeWorkingThreads) == 0)
//                {
//                    _allThreadsQuit.Set();
//                }
//                else
//                {
//                    _commands.Add(new DummyCommand());
//                }
//            }
//        }
//
//        private void DrainCommandQueue()
//        {
//            Command command;
//                
//            while (_commands.TryTake(out command))
//            {
//                command.Execute();
//            }
//        }
//
//        private void DequeueAndRunTask()
//        {
//            Command task = _commands.Take();
//            task.Execute();
//        }
//
//        public void Dispose()
//        {
//            lock (_disposalInProgressCriticalSection)
//            {
//                if (_disposed)
//                {
//                    return;
//                }
//
//                _isDisposing = true;
//
//                _commands.Add(new DummyCommand());
//
//                _allThreadsQuit.WaitOne();
//
//                _allThreadsQuit.Close();
//
//                _disposed = true;
//            }
//        }
//    }
//}